package com.naiterui.ehp.bs.patient.utils;

import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <一句话简述>
 *
 * @author Amber E-mail:E-mail地址
 * @version 2015年7月6日 上午1:02:55 by Amber
 * @Description <详细描述>
 * @see <接口/父类>
 */
public class StringUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(StringUtil.class);

    /**
     * 检测是否有emoji字符
     *
     * @param source
     *
     * @return 一旦含有就抛出
     */

    public static boolean containsEmoji(String source) {

        if (StringUtils.isBlank(source)) {
            return false;
        }
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint)) {
                // do nothing，判断到了这里表明，确认有表情字符
                return true;
            }
        }
        return false;
    }

    private static boolean isEmojiCharacter(char codePoint) {

        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA) || (codePoint == 0xD) || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD));

    }

    /**
     * 过滤emoji 或者 其他非文字类型的字符
     *
     * @param source
     *
     * @return
     */
    public static String filterEmoji(String source) {

        if (!containsEmoji(source)) {
            return source;// 如果不包含，直接返回
        }
        // 到这里铁定包含
        StringBuilder buf = null;
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint)) {
                if (buf == null) {
                    buf = new StringBuilder(source.length());
                }
                buf.append(codePoint);
            }
        }
        if (buf == null) {
            return source;// 如果没有找到 emoji表情，则返回源字符串
        } else {
            if (buf.length() == len) {// 这里的意义在于尽可能少的toString，因为会重新生成字符串
                buf = null;
                return source;
            } else {
                return buf.toString();
            }
        }

    }

    /**
     * 获取字符串unicode编码
     *
     * @param str
     *
     * @return
     */
    public static String encodeUnicode(String str) {
        if (StringUtils.isEmpty(str)) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        int i = 0;
        do {
            char c = str.charAt(i);
            sb.append("\\u").append(Integer.toHexString(c));
        } while (++i < str.length());
        return sb.toString();
    }

    /**
     * 获取Unicode对应字符串
     *
     * @param theString
     *
     * @return
     */
    private static String decodeUnicode(String theString) {
        char aChar;
        int len = theString.length();
        StringBuilder outBuffer = new StringBuilder(len);
        for (int x = 0; x < len; ) {
            aChar = theString.charAt(x++);
            if (aChar == '\\') {
                aChar = theString.charAt(x++);
                if (aChar == 'u') {
                    // Read the xxxx
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = theString.charAt(x++);
                        switch (aChar) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException("Malformed   \\uxxxx   encoding.");
                        }

                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't') {
                        aChar = '\t';
                    } else if (aChar == 'r') {
                        aChar = '\r';
                    } else if (aChar == 'n') {
                        aChar = '\n';
                    } else if (aChar == 'f') {
                        aChar = '\f';
                    }
                    outBuffer.append(aChar);
                }
            } else {
                outBuffer.append(aChar);
            }
        }
        return outBuffer.toString();
    }

    /**
     * 处理emoji表情等特殊字符（依赖redis缓存）
     *
     * @param source
     *
     * @return
     */
    public static String handleEmoji(String source) {

        LOGGER.info("---------- handle emoji code START ; sourceUnicode 【{}】,source 【{}】", encodeUnicode(source), source);

        Set<String> regexSet = EmojiUtil.getRegexSet();
        Set<String> instanceSet = EmojiUtil.getInstanceSet();
        if (StringUtils.isEmpty(source)) {
            LOGGER.info("---------- handle emoji code ; source is empty");
            return "";
        }

        // 现有处理逻辑
        source = filterEmoji(source);

        // 处理缓存正则(例如：[^\u0000-\uFFFF])
        for (String regex : regexSet) {
            if (!StringUtils.isEmpty(source)) {
                source = source.replaceAll(regex, "");
            }
        }

        // 处理缓存Unicode特例
        for (String instance : instanceSet) {
            if (!StringUtils.isEmpty(source)) {
                while (!StringUtils.isEmpty(source) && encodeUnicode(source).contains(instance)) {
                    source = decodeUnicode(encodeUnicode(source).replace(instance, ""));
                }
            }
        }
        LOGGER.info("---------- handle emoji code END ; resultUnicode 【{}】,result 【{}】", encodeUnicode(source), source);
        return source;
    }

    /**
     * @param name
     *
     * @return
     *
     * @throws
     * @method
     * @author chengqiang
     * @description 验证真实姓名合法性[汉字，字母]
     * @date 2018/11/27 13:36
     **/
    public static boolean valRealName(String name) {
        String regex = "^[\\u4E00-\\u9FA5A-Za-z]+$";
        return name.matches(regex);
    }

    /**
     * 加密手机中间4位
     *
     * @param phone
     *
     * @return
     */
    public static String securePhone(String phone) {
        if (StringUtils.isNotBlank(phone)) {
            return phone.replaceAll("^(.{3})(.{4})(.{4})", "$1****$3");
        }
        //若非正常手机格式，原样输出
        return phone;
    }

    /**
     * 加密身份证中间4位
     *
     * @param phone
     *
     * @return
     */
    public static String secureIdcard(String idcard) {
        if (StringUtils.isBlank(idcard)) {
            return idcard;
        }
        if (idcard.length() == 15) {
            return idcard.replaceAll("^(.{3})(.*)(.{3})", "$1*********$3");
        } else if (idcard.length() == 18) {
            return idcard.replaceAll("^(.{3})(.*)(.{3})", "$1************$3");
        } else {
            return idcard.replaceAll("^(.{3})(.*)(.{3})", "$1************$3");
        }
    }

}
